#!/usr/bin/env python
# encoding: utf-8

import unittest
from StringIO import StringIO
from soapsim.app import SimulatorApp
from soapsim.settings import SimulatorSettings
from testutils import send_request

CONFIGS = """
name: Calculator Service Simulator
port: 32555
operations:
- soapaction: http://example.com/calculator/execute
  default_response: |
        <OperationResult xmlns="http://example.com/calculator">-1</OperationResult>
  reactions:
    - key: ADD
      response: |
        <OperationResult xmlns="http://example.com/calculator">3</OperationResult>
    - key: MULTIPLY
      response: |
        <OperationResult xmlns="http://example.com/calculator">250</OperationResult>
"""
class TestSimulatorApp(unittest.TestCase):
    
    def setUp(self):
        self.config_file = StringIO(CONFIGS)
        self.settings = SimulatorSettings(self.config_file)
        self.app = SimulatorApp(self.settings)

    def testMissingSoapAction(self):
        response = send_request(self.app, soapaction="http://missing")
        self.assert_(response.status.startswith('500'))
        self.assert_("Missing operation" in response.body)
    
    def testMissingDefaultResponse(self):
        del self.settings.operations[0].op['default_response']
        response = send_request(self.app, 
            soapaction="http://example.com/calculator/execute")
        self.assert_(response.status.startswith('500'))
        self.assert_("InvalidSettingsException" in response.body)
    
    def testSuccessWithWrap(self):
        op = self.settings.operations[0]
        reaction = op.reactions[0]
        response = send_request(self.app, 
            soapaction=op.soapaction,
            body=reaction.key)
        self.assert_(response.status.startswith('200'))
        self.assert_(reaction.response in response.body)
        self.assert_("soapenv:Body" in response.body)

    def testSuccessWithoutWrap(self):
        op = self.settings.operations[0]
        op.op['wrap'] = 'False'
        reaction = op.reactions[0]
        response = send_request(self.app, 
            soapaction=op.soapaction,
            body=reaction.key)
        self.assert_(response.status.startswith('200'))
        self.assert_(reaction.response in response.body)
        self.assert_("soapenv:Body" not in response.body)
    
    def testDefaultResponse(self):
        response = send_request(self.app, 
            soapaction="http://example.com/calculator/execute",
            body="NOOP")
        self.assert_(response.status.startswith('200'))
        self.assert_(self.settings.operations[0].default_response
                        in response.body)

    def testDelay(self):
        op = self.settings.operations[0]
        op.op['delay'] = 3
        from time import time
        before = time()
        send_request(self.app, soapaction=op.soapaction, body="ADD")
        after = time()
        duration = after - before
        self.assert_(3 < duration < 4)
        
if __name__ == '__main__':
    unittest.main()